#coding=utf-8
'''
Created on 2017-04-26

@author: sandy
'''

from twisted.internet import task
import logging
from pycommon import Const,DbPool,Utils
import GameDb
import ClientBuild
import TimeCheck

class PlatformDB(object):
    def __init__(self):
        self.__linkcount = 0
        self.__dbp = None
    def start(self,db,user,passwd,host = u'127.0.0.1',port = 3306,linkcount = 3):
        logging.info("PlatformDb host=%s db=%s user=%s passwd=%s",host,db,user,passwd)
        l = task.LoopingCall(self.onTimer)
        l.start(10, False)
        self.__linkcount = linkcount
        self.__dbp = DbPool.DBConnectionPool(db = db,user = user,passwd = passwd,host = host,port = port,linkcount = linkcount)
        self.__dbp.start()
        

    def stop(self):
        self.__dbp.stop()
        
    def onTimer(self):
        self.doTask()
    
    def doTask(self):
        pass
            
    def hashIndex(self, uid):
        return uid % self.__linkcount
    
    def hashIndexAccount(self, account):
        return ord(account[0]) % self.__linkcount  
    
    def query(self, conindex, ctx, sql, params, func):
        self.__dbp.query(conindex, ctx, sql, params, func)

    def execute(self, conindex, ctx, sql, params, func):
        self.__dbp.execute(conindex, ctx, sql, params, func)

################################################################  HTTP  ##########################################
    def loginHTTP(self, account, passwd,cbk):
        logging.debug(u"PlatformDb login")
        passwdsign = Utils.passwdHash(account, passwd)
        sql = u"call p_aa_login(%s, %s,%s,%s)"
        params = (account, passwdsign,'',Const.GAME_ID)
        ctx = (account,cbk)
        self.query(self.hashIndexAccount(account),ctx,sql,params,self.loginResultHTTP)

    def loginResultHTTP(self, ctx, error, rows):
        account,cbk = ctx
        if error:
            logging.error(u"login2Result() FAIL, account=%s err=%s", account, error)
            cbk(0,0)
            return
        logging.debug(u"PlatformDb loginResult")
        ret = int(rows[0][0])
        if ret != Const.ERR_OK:
            logging.error(u"loginResult() FAIL, ret=%d", ret)
            cbk(ret,0)
            return
        uid = int(rows[0][1])
        if ret == Const.ERR_OK:
            GameDb.instance.loginHTTP(uid,account,cbk)
        elif cbk:
            cbk(ret,uid)

    def registerHTTP(self, account, passwd,cbk):
        passwdsign = Utils.passwdHash(account, passwd)
        sql = u"call p_aa_register(%s, %s,%s)"
        params = (account, passwdsign,'')
        ctx = (account, passwd,cbk)
        self.query(self.hashIndexAccount(account),ctx,sql,params,self.registerResultHTTP)

    def registerResultHTTP(self, ctx, error, rows):
        account, passwd,cbk = ctx
        if error:
            logging.error(u"registerResult() FAIL, account=%s err=%s", account, error)
            cbk(0)
            return
        logging.debug(u"PlatformDb registerResult")
        ret = int(rows[0][0])
        if ret != Const.ERR_OK:
            logging.error(u"registerResult() FAIL, ret=%d", ret)
            cbk(ret,0)
            return
        uid = int(rows[0][1])
        if ret == Const.ERR_OK:
            GameDb.instance.registerHTTP(uid,account,cbk)
        elif cbk:
            cbk(ret)
        
################################################################## TCP ##################################    
    def login(self, client,account, passwd):
        logging.debug(u"PlatformDb login account=%s",account)
        passwdsign = Utils.passwdHash(account, passwd)
        sql = u"call p_aa_login(%s, %s ,%s,%s)"
        params = (account, passwdsign,client.getIp(),Const.GAME_ID)
        ctx = (client,account)
        self.query(self.hashIndexAccount(account),ctx,sql,params,self.loginResult)
    
    def loginResult(self, ctx, error, rows):
        client,account = ctx
        if error:
            logging.error(u"login2Result() FAIL, account=%s err=%s", account, error)
            return
        logging.debug(u"PlatformDb loginResult")
        ret = int(rows[0][0])
        if ret != Const.ERR_OK:
            logging.error(u"loginResult() FAIL, ret=%d", ret)
            client.sendPacket(ClientBuild.loginResult(ret,0,u''))
            if ret==Const.ERR_PASSWD_WRONG:
                TimeCheck.instance.addLoginFail(account)
        else:
            uid = int(rows[0][1])
            GameDb.instance.login(client,uid,account)

    def register(self,client, account, passwd):
        passwdsign = Utils.passwdHash(account, passwd)
        sql = u"call p_aa_register(%s, %s,%s)"
        params = (account, passwdsign,client.getIp())
        ctx = (client,account, passwd)
        self.query(self.hashIndexAccount(account),ctx,sql,params,self.registerResult)
    

    def registerResult(self, ctx, error, rows):
        client,account, passwd = ctx
        if error:
            logging.error(u"registerResult() FAIL, account=%s err=%s", account, error)
            return
        logging.debug(u"PlatformDb registerResult")
        ret = int(rows[0][0])
        if ret != Const.ERR_OK:
            logging.error(u"registerResult() FAIL, ret=%d", ret)
            client.sendPacket(ClientBuild.registerResult(ret))
        else:
            GameDb.instance.register(client,int(rows[0][1]),account)


    def registerAuto(self, client, passwd, regip):
        sql = u"call p_aa_register_auto(%s,%s,%s)"
        account = u'm-tmpaccount'
        pwdhash = Utils.passwdHash(account, passwd)
        params = (pwdhash,regip,Const.GAME_ID)
        ctx = (client, passwd, regip, pwdhash)
        self.query(self.hashIndexAccount(account),ctx,sql,params,self.registerAutoResult)
        
    def registerAutoResult(self, ctx, error, rows):
        client, passwd, regip, pwdhash = ctx
        if error:
            logging.error(u"p.registerAutoResult() FAIL regip=%s err=%s", regip, error)
            client.sendPacket(ClientBuild.registerResult(Const.ERR_DATABASE))
            return
        ret = int(rows[0][0])
        uid = int(rows[0][1])
        account = rows[0][2]
        if ret != Const.ERR_OK:
            logging.error(u"p.registerResult() FAIL regip=%s ret=%d", regip, ret)
            client.sendPacket(ClientBuild.registerResult(ret))
            return
        newPwdHash = Utils.passwdHash(account, passwd)
        self.updateAutoRegisterPasswd(client, uid, account, passwd, pwdhash, newPwdHash)
                
    def updateAutoRegisterPasswd(self, client, uid, account, passwd, poldpasswdhash, pnewpasswdhash):
        sql = u"call p_aa_update_passwd(%s,%s,%s)"
        params = (uid,poldpasswdhash,pnewpasswdhash)
        ctx = (client, uid, account, passwd)          
        self.query(self.hashIndex(uid),ctx,sql,params,self.updateAutoRegisterPasswdResult) 
        
    def updateAutoRegisterPasswdResult(self, ctx, error, rows):  
        client, uid, account, passwd = ctx
        if error:
            logging.error(u"p.updatePasswdResult() uid=%d, err=%s",uid,str(error))
            client.sendPacket(clientbuild.registerResult(Const.ERR_DATABASE))
            return
        ret = int(rows[0][0])
        if ret == Const.ERR_OK: 
            client.sendPacket(ClientBuild.registerResult(Const.ERR_OK,account, passwd))
        else:
            client.sendPacket(ClientBuild.registerResult(ret)) 
     

instance = PlatformDB()

if __name__ == '__main__':
    pass